package steed.util.file;

import java.io.File;
import java.io.IOException;
import java.net.FileNameMap;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;

import javax.servlet.http.Part;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;

import steed.util.base.BaseUtil;
import steed.util.base.PropertyUtil;
import steed.util.base.StringUtil;

/**
 * 阿里云OSS文件引擎
 * @author 战马
 *
 */
public class AliyunOSSEngine implements FileEngine {
	 private String endpoint = PropertyUtil.getConfig("aliyun.oss.endpoint");
     private String accessKeyId = PropertyUtil.getConfig("aliyun.oss.accessKeyId");
     private String accessKeySecret = PropertyUtil.getConfig("aliyun.oss.accessKeySecret");
     private String bucketName = PropertyUtil.getConfig("aliyun.oss.bucketName");
     private OSSClient ossClient;
     
	 public AliyunOSSEngine() {
		 try {
			 ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);  /*
			  * Determine whether the bucket exists
			  */
			 if (!ossClient.doesBucketExist(bucketName)) {
				 /*
				  * Create a new OSS bucket
				  */
				 BaseUtil.getLogger().debug("Creating bucket {}", bucketName);
				 ossClient.createBucket(bucketName);
				 CreateBucketRequest createBucketRequest= new CreateBucketRequest(bucketName);
				 createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
				 ossClient.createBucket(createBucketRequest);
			 }
		} catch (OSSException e) {
			BaseUtil.getLogger().error("阿里云oss初始化失败!",e);
		}

	}

	 
	public OSSClient getOssClient() {
		return ossClient;
	}
	 
	 /* (non-Javadoc)
	 * @see steed.util.file.FileEngine#upload(java.lang.String, java.io.File)
	 */
	@Override
	public String upload(String key,File file){
		return upload(key, file, null);
	}
	
	@Override
	public File getFile(String key){
		try {
			File createTempFile = File.createTempFile(key, null);
			OSSObject object = ossClient.getObject(new GetObjectRequest(bucketName, key));
			return createTempFile;
		} catch (IOException e) {
			BaseUtil.getLogger().error("创建临时文件出错!",e);
		}
		return null;
	}
	
/*	@Override
	public String upload(String key,File file,String fileName){
		BaseUtil.getLogger().debug("开始上传文件到阿里云OSS:{}",key);
		ObjectMetadata objectMetadata = new ObjectMetadata();
		if (fileName != null) {
			//TODO 通过文件开头识别文件类型
			try {
				objectMetadata.setContentType(Files.probeContentType(Paths.get(fileName)));
			} catch (IOException e) {
				BaseUtil.getLogger().warn("获取文件mime类型失败!",e);
			}
		}
		PutObjectResult putObject = ossClient.putObject(new PutObjectRequest(bucketName, key, file,objectMetadata));
		return key;
		//为跟单机引擎统一,这里不返回md5
//		return putObject.getETag();
	}
*/	@Override
	public String upload(String key,File file,String fileName){
		ObjectMetadata objectMetadata = new ObjectMetadata();
		if (fileName != null) {
			//TODO 通过文件开头字节识别文件类型
//				String probeContentType = Files.probeContentType(Paths.get(fileName));//linux下获取不到mime
			FileNameMap fileNameMap = URLConnection.getFileNameMap(); 
		    String probeContentType = fileNameMap.getContentTypeFor(fileName);  
			objectMetadata.setContentType(probeContentType);
		}
		BaseUtil.getLogger().debug("开始上传文件到阿里云OSS:key:{},file:{},fileName:{},mime:{}",key,file,fileName,objectMetadata.getContentType());
		PutObjectResult putObject = ossClient.putObject(new PutObjectRequest(bucketName, key, file,objectMetadata));
		return key;
		//为跟单机引擎统一,这里不返回md5
//		return putObject.getETag();
	}

	

	/* (non-Javadoc)
	 * @see steed.util.file.FileEngine#getHttpUrl(java.lang.String, java.lang.Long)
	 */
	@Override
	public String getHttpUrl(String key,Long  effectiveTime ){
		Date expiration = new Date(System.currentTimeMillis() + effectiveTime);
		return getHttpUrl(key, expiration);
	}


	@Override
	public String getHttpUrl(String key, Date expireDate) {
		// 生成URL
		URL url = ossClient.generatePresignedUrl(bucketName, key, expireDate);
		return url.toString().replace("-internal", "");
	}
	
	
	/* (non-Javadoc)
	 * @see steed.util.file.FileEngine#getHttpUrl(java.lang.String)
	 */
	@Override
	public String getHttpUrl(String key){
		return getHttpUrl(key, 1000*60*10L);
	}
	
	/* (non-Javadoc)
	 * @see steed.util.file.FileEngine#delete(java.lang.String)
	 */
	@Override
	public boolean delete(String key){
		try {
			BaseUtil.getLogger().debug("删除阿里云OSS文件:{})",key);
			ossClient.deleteObject(bucketName, key);
			return true;
		} catch (OSSException e) {
			BaseUtil.getLogger().error("删除阿里云OSS文件失败!",e);
			return false;
		}
	}


//	@Override
//	public String upload(String key, Part part) {
//		ObjectMetadata objectMetadata = new ObjectMetadata();
//		objectMetadata.setContentType(part.getContentType());
//		BaseUtil.getLogger().debug("开始上传文件到阿里云OSS:key:{},part:{},fileName:{},mime:{}",key,part.getName(),part.getSubmittedFileName(),objectMetadata.getContentType());
//		try {
//			PutObjectResult putObject = ossClient.putObject(new PutObjectRequest(bucketName, key, part.getInputStream(),objectMetadata));
//			return key;
//		} catch (OSSException | IOException | ClientException e) {
//			BaseUtil.getLogger().error("上传文件失败!",e);
//		}
//		return "steedUploadFileError";
//	}
	
}
